<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Vue + Element 多级表头</title>
  <link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.14/lib/theme-chalk/index.css">
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/element-ui/lib/index.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/xlsx/dist/xlsx.full.min.js"></script>
</head>
<body>
  <div id="app">

    <div class="fixed-header">
        <el-button type="primary" @click="showPopup = true">添加 IP</el-button> 
        <el-button type="primary" @click="searchIpDailog">搜索 IP</el-button>  
        <a type="button" 
        href="/index/getIpData?export=1" 
        class="el-button el-button--primary" 
        style="text-decoration: none;margin-left: 10px;">导出文件</a> 

        <el-button type="warning" @click="resetLoginData" style="float: right;">退出登录</el-button>
        <!-- <a href="__PUBLIC__/Admin/Statics/example.xlsx" style="text-decoration: none;color: #409EFF;">导入模板</a>  -->
    </div>

    <div class="table-container-wrapper">
        <div class="table-container">
            <el-table  
                :data="generateTableData()"
                border
                style="width: 100%;"
                :max-height="790"
                :header-cell-style="{ position: 'sticky', top: '0', background: '#f5f7fa', zIndex: 1 }"
            >
                <!-- 第一层表头：不同的规则组 -->
                <el-table-column
                v-for="(group, groupIndex) in groups"
                :key="groupIndex"
                :label="`服务器总览 (IP总量: ${ruleIpCount[group.name] || 0})`"
                align="center"
                
                > 
                <!-- 第二层表头：子组 -->
                <el-table-column
                    v-for="(subGroup, subIndex) in group.subGroups"
                    :key="subIndex" 
                    align="center"
                    min-width="200"  
                >
                <template slot="header">
                    <div>  
                        {{ subGroup.name }} ({{ subGroup.count || 0 }}) 
                        <el-button
                            type="text"
                            icon="el-icon-plus"
                            @click.stop="openAddDialog(group.name,subGroup.name)"
                            title="添加 IP"
                            style="margin-left: 5px;" 
                        ></el-button>
                        <el-button
                            type="text"
                            icon="el-icon-time"
                            @click.stop="rentIpTime(group.name,subGroup.name)"
                            title="租用 IP"
                            style="margin-left: 5px;"
                        ></el-button>
                        <el-button
                            type="text"
                            icon="el-icon-delete"
                            @click.stop="deleteIpByGroup(group.name,subGroup.name)"
                            title="删除该服务器所有 IP"
                            style="margin-left: 5px;"
                        ></el-button>
                        <el-button
                            type="text"
                            icon="el-icon-document-copy"
                            @click.stop="copyIps(group.name,subGroup.name)"
                            title="复制该服务器所有 IP"
                            style="margin-left: 5px;"
                        ></el-button> 
                        <br>
                        <span style="color: rgb(204, 119, 140); white-space: nowrap;  " 
                        title="">租用时间:</span>
                        <br>
                         <span style="color: rgb(204, 119, 140); white-space: nowrap;  " 
                        title="租用时间">{{formatTimestamp(subGroup.time)}}</span>
                        <br> 
                    </div>
                </template> 
                    <template slot-scope="scope"> 
                    <el-popover
                        placement="right"
                        trigger="hover">
                        <div v-html="getIpDetail(scope.row[`ip_${groupIndex}_${subIndex}`])"></div>
                        <span   slot="reference" 
                                @click="handleServerClick($event, scope.row[`ip_${groupIndex}_${subIndex}`])" 
                                :style="{
                                    cursor: 'pointer',
                                    color:  '#409EFF'
                                }">
                                 
                                {{ scope.row[`ip_${groupIndex}_${subIndex}`] }}  
                        </span>
                    </el-popover> 

                    </template>
                </el-table-column>
                </el-table-column>
            </el-table>
        </div>

        
    </div>

    <!-- 弹窗组件 -->
    <el-dialog title="新增 IP" 
    :visible.sync="showPopup" 
    width="25%" 
    @close="handleDialogClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false">
        <el-form :model="ipForm" label-width="120px">   
            <el-form-item label="主IP">
                <el-input
                    type="text"
                    v-model="ipForm.serverAddrOne"
                    class="inputWidth"
                    clearable>
                </el-input>
            </el-form-item>  
            <el-form-item label="IP 地址" >
                <el-input
                    type="textarea"
                    v-model="ipForm.serverAddr"
                    placeholder="一行一个 IP 地址"
                    class="inputWidth"
                    rows="5"
                    clearable>
                </el-input> 
            </el-form-item>
        </el-form>

        <div slot="footer" class="dialog-footer">
            <el-button @click="handleDialogClose">取消</el-button> 
            <el-button type="primary" @click="submitIpForm">提交</el-button>
        </div>
    </el-dialog>  

  <el-dialog
  title="IP详情"
  :visible.sync="ipDetailsVisible"
  width="30%"
  :close-on-click-modal="false"
  :close-on-press-escape="false">
  <div>
      <el-form :model="showCurrentIpDetails"> 
          <el-form-item label="IP地址">
              <el-input v-model="showCurrentIpDetails.server_addr" clearable ></el-input>
          </el-form-item>
           
          <el-form-item label="IP类型"> 
            <el-radio-group v-model="showCurrentIpDetails.is_main_addr"> 
                <el-radio-button :label="2">主IP</el-radio-button> 
                <el-radio-button :label="0">普通IP</el-radio-button>
            </el-radio-group> 
         </el-form-item> 
          <p><strong>所属服务器:</strong> 服务器{{ showCurrentIpDetails.server_id }}</p>
          <p><strong>创建时间:</strong> {{ formatTimestamp(showCurrentIpDetails.create_time) }}</p>
          <p><strong>租用时间:</strong> {{ formatTimestamp(showCurrentIpDetails.rent_time) }}</p>
          <p><strong>更新时间:</strong> {{ formatTimestamp(showCurrentIpDetails.update_time) }}</p>
          <!-- <p> 
            <el-switch v-model="showCurrentIpDetails.status" 
            active-value="0" 
            inactive-value="1"
            active-text="启用"
            inactive-text="禁用" 
            inactive-color="#ff4949"  
            ></el-switch></p> -->
           
      </el-form>
  </div>
  <div slot="footer" class="dialog-footer">
        <el-button type="danger"  @click="deleteDialogIp('delete')">删除</el-button> 
      <el-button  @click="ipDetailsVisible = false">取消</el-button>
      <el-button  type="primary" @click="saveIpDetails">保存</el-button>
  </div>
  </el-dialog>

  <el-dialog
      title="添加 IP"
      :visible.sync="addDialogVisible"
      width="30%"
      :close-on-click-modal="false"
      :close-on-press-escape="false">
      <div>
          <el-form :model="newIpDetails">
              <el-form-item label="IP 地址">
                  <el-input v-model="newIpDetails.server_addr" clearable></el-input>
              </el-form-item>   
              <!-- <p><span>是否主IP </span>
              <el-switch v-model="newIpDetails.is_main_addr" active-value="2" inactive-value="0"></el-switch></p>
                         -->
              <p> 
                <el-switch v-model="newIpDetails.is_main_addr" 
                    active-value="2" 
                    inactive-value="0"
                    active-text="主 IP"
                    inactive-text="非主 IP"  
                >
                </el-switch>
            </p>
              <el-form-item label="所属服务器">
                  <el-input v-model="newIpDetails.group_id" disabled></el-input>
              </el-form-item>
          </el-form>
      </div>
      <div slot="footer" class="dialog-footer">
          <el-button @click="addDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveNewIp">保存</el-button>
      </div>
  </el-dialog>
  <el-dialog
    title="选择租用时间"
    :visible.sync="showDateTimeDialog"
    width="30%"
    @close="showDateTimeDialog = false"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
>
    <el-date-picker
        v-model="selectedRentTime"
        type="datetime"
        placeholder="选择租用时间"
        format="yyyy-MM-dd HH:mm:ss"
        value-format="yyyy-MM-dd HH:mm:ss"
        style="width: 100%; margin-bottom: 15px;"
    ></el-date-picker>
    <div slot="footer" class="dialog-footer">
        <el-button @click="showDateTimeDialog = false">取消</el-button>
        <el-button type="primary" @click="submitRentTime">确定</el-button>
    </div>
</el-dialog>

<el-dialog
    title="搜索 IP"
    :visible.sync="showIpSearchDialog"
    width="30%"
    @close="closeIpSearch"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
> 
    <el-input v-model="inputIpVal" clearable @keydown.native.enter="searchIpDetail"></el-input>
    <div slot="footer" class="dialog-footer">
        <el-button @click="closeIpSearch">取消</el-button>
        <el-button type="primary" @click="searchIpDetail">确定</el-button>
    </div>
</el-dialog>



        <el-button 
            v-if="showBackToTop" 
            @click="scrollToTop" 
            type="primary" 
            icon="el-icon-arrow-up" 
            circle 
            class="back-to-top">
        </el-button> 
        <el-button 
            v-if="showBackToBottom" 
            @click="scrollToBottom" 
            type="primary" 
            icon="el-icon-arrow-down" 
            circle 
            class="scroll-to-bottom">
        </el-button> 


    
  </div>

  <script>
    new Vue({
        el: '#app',
        data() {
            return {
                    groups: [], 
                    el_table_data: [],
                    dialogVisible: false, // 控制弹窗显示
                    selectedGroup: '', // 选中的分组名称 
                    uploadData: {} ,
                    showDateTimeDialog:false,
                    showIpSearchDialog:false,
                    selectedRentTime:null,
                    inputIpVal:'',
                    rawData: {},
                    exportData:{},
                    allData:{},
                    transformedData: [],
                    ipDetailsVisible: false,
                    currentIpDetails: {}, // 存储当前 IP 的详细信息
                     
                    ipDetails: {},
                    originalIp: "",  
                    originalIpDetails:{},
                    showCurrentIpDetails: {
                        server_addr: '',
                        is_main_addr: '',
                        rule_name: '',
                        rule_id: '',
                        server_id: '',
                        create_time: '',
                        update_time: '',
                        status:'', 
                    },
                    ruleList:{},
                    addDialogVisible: false,
                    newIpDetails: {
                        server_addr: '',
                        is_main_addr: false,
                        rule_name: '',
                        group_id: ''
                    },
                    ruleIpCount:{},
                    //以前的添加IP
                    ipForm: { 
                        serverAddr: '',
                        serverAddrOne: '', //主IP 
                    },  
                    showPopup: false,
                    showBackToTop: false,
                    showBackToBottom:false,
                    showManBackToTop: false,
                    
                    //管理IP
                    ipSearchQuery: '',
                    ruleSearchQuery:'',
                    mainIpFilter:'', 
                    serverFilter:'',
                    showManageIp: false, // 控制弹窗显示
                    ipManageTableData: [], // 存储表格数据
                    showTotalCount : false,
                    totalCount: '',
                    searchQuery: '', // 搜索关键字
                    columnWidths: { // 自定义列宽
                        id: '80px',
                        name: '200px',
                        server: '150px',
                        ip: '300px',
                    },
                    selectedIps: [], // 存储选中的 IP
                    searchIP: '',  // 存储 IP 搜索关键字
                    selectedRule: '',  // 存储选中的规则 ID
                    dateRange: '',
                    selectedColumn: 'server_addr',
                    selectedRows: [] ,// 存储已选择的行
                    filteredData: [], 
                    changeRuleId:null, 
                    tableWidth: 0, 
                    tableMaxHeight: 790,
            };
        }, 
        computed: {
            dynamicColumnWidth() {
                // 根据窗口宽度、组和子组数量来动态计算列宽
                const totalColumns = this.groups.reduce((sum, group) => sum + group.subGroups.length, 0);
                const baseWidth = this.tableWidth / totalColumns;
                return Math.max(baseWidth, 250); // 180为最小宽度
            }
        }, 
        mounted() {
            const loginData = this.checkLoginData(); // 获取登录数据
            

            // 只有当 loginData 存在并且 username 为 'user123' 时才进行数据请求
            if (loginData && loginData.username != '') {
                this.fetchIpData();   
                
                this.$nextTick(() => {
                    const tableWrapper = this.$el.querySelector('.el-table__body-wrapper');
                    if (tableWrapper) {
                        tableWrapper.addEventListener('scroll', this.handleScroll, { passive: true });
                    }
                });

                this.updateTableHeight(); // 初始调用
                window.addEventListener('resize', this.updateTableHeight); // 监听窗口变化
            } else {
                // 可以在这里处理未匹配的情况，例如导航到登录页面或显示提示信息
                //window.location.href = 'http://192.168.200.57:8088/index.php'; 
                window.location.href = window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/index.php'; 
            }
        },
        beforeDestroy() {
            // 移除事件监听
            const tableWrapper = this.$el.querySelector('.el-table__body-wrapper');
            tableWrapper.removeEventListener('scroll', this.handleScroll);

            window.removeEventListener('resize', this.updateTableHeight); // 移除监听
        },
        methods: {   
                resetLoginData() {
                    localStorage.removeItem('username');
                    localStorage.removeItem('password');
                    localStorage.removeItem('expires');  
                    window.location.href = window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/index.php'; 
                },
                checkLoginData() {
                    const username = localStorage.getItem('username');
                    const password = localStorage.getItem('password');
                    const expires = localStorage.getItem('expires');

                    if (username && password && expires) {
                        const expiresDate = new Date(parseInt(expires));
                        const now = new Date();

                        if (now < expiresDate) {
                            // 数据未过期，返回用户名和密码
                            return { username, password };
                        } else {
                            // 已过期，清除数据
                            localStorage.removeItem('username');
                            localStorage.removeItem('password');
                            localStorage.removeItem('expires');
                        }
                    } 
                    return null; // 数据不存在或已过期
                },
                onDialogOpened() {
                    if (this.$refs.ipDailogTable && this.$refs.ipDailogTable.$el) {
                        const tableBodyWrapper = this.$refs.ipDailogTable.$el.querySelector('.el-table__body-wrapper');
                        // 添加滚动监听
                        tableBodyWrapper.addEventListener('scroll', this.handleTableScroll);
                    } else {
                        console.warn('ipDailogTable ref not found');
                    }
                },
                updateTableHeight() {
                    const viewportHeight = window.innerHeight;
                    const headerHeight = 100;  
                    this.tableMaxHeight = viewportHeight - headerHeight;   
                },
                updateTableWidth() {
                    this.tableWidth = document.querySelector(".el-table").offsetWidth;
                },
                fetchIpData() {
                    axios.get('/index/getIpData').then((response) => {
                        this.rawData = response.data.data;
                        this.exportData = response.data.data;
                        this.allData = response.data.allData;
                        this.ruleIpCount = response.data.ruleIpCount || {};
                        this.assembleTransformedData(this.rawData, this.ruleIpCount);
                        this.generateTableData();
                        this.processIpDetails(this.allData); 
                        this.exportData = this.exportedConvertData(this.exportData, this.ruleIpCount);
                    }).catch((error) => {
                        console.error("获取 IP 数据出错:", error);
                    });
                },
                exportedConvertData(rawData, ruleIpCount) {
                    // 按 ruleIpCount 的值降序排序
                    const sortedRooms = Object.keys(ruleIpCount).sort((a, b) => ruleIpCount[b] - ruleIpCount[a]); 
                    // 组装 transformedData 数组
                    return sortedRooms.map(room => {
                        const groups = rawData[room] ? Object.entries(rawData[room]).map(([key, value]) => ({ 
                            groupId: key,
                            time: this.formatTimestamp(value.time),
                            ips: value.ips,
                            count: value.count,
                        })) : [];

                        return { room, groups };
                    });
                },
                assembleTransformedData(rawData, ruleIpCount) {
                    const groups = [];
                    const transformedData = {}; 
                    const sortedRooms = Object.keys(ruleIpCount).sort((a, b) => ruleIpCount[b] - ruleIpCount[a]); 
                    sortedRooms.forEach((ruleName) => { 
                            const groupEntries = rawData[ruleName];
                            if (!groupEntries) return; 
                            const subGroups = Object.keys(groupEntries).map(groupKey => {
                                const groupInfo = groupEntries[groupKey]; 
                                return {
                                    name: `服务器${groupKey}`,
                                    time: groupInfo.time ? groupInfo.time : '无',
                                    count:groupInfo.count, 
                                };
                            });
                            groups.push({ name: ruleName, subGroups });

                            transformedData[ruleName] = {};
                            Object.entries(groupEntries).forEach(([groupKey, groupInfo]) => {
                            transformedData[ruleName][groupKey] = groupInfo.ips.map(ipInfo => {
                                let ipWithCheckmark = ipInfo.ip; 
                                if(ipInfo.is_main_addr === "2"){
                                    ipWithCheckmark = `${ipInfo.ip} 主`;
                                }  
                                let status = ipInfo.status;
                                return { ip: ipWithCheckmark,status};
                            });
                        });
                    }); 
                    this.groups = groups;
                    this.rawData = transformedData; 
                },
                generateTableData() {
                    const tableData = [];
                    let maxRows = 0;

                    Object.values(this.rawData).forEach(groups => {
                        Object.values(groups).forEach(ips => {
                            maxRows = Math.max(maxRows, ips.length);
                        });
                    });

                    for (let rowIndex = 0; rowIndex < maxRows; rowIndex++) {
                            const row = {};
                            this.groups.forEach((group, groupIndex) => {
                                group.subGroups.forEach((subGroup, subIndex) => { 
                                    const groupName = group.name;
                                    const subGroupName = subGroup.name.replace("服务器", "").trim();
                                    const ipList = this.rawData[groupName] && this.rawData[groupName][subGroupName]; 
                                    
                                    row[`ip_${groupIndex}_${subIndex}`] = ipList && ipList[rowIndex] ? ipList[rowIndex].ip : "";
                                    row[`ip_${groupIndex}_${subIndex}_status`] = ipList && ipList[rowIndex] ? ipList[rowIndex].status : 0;
                                     
                                });
                            });
                        tableData.push(row);
                    } 
                    this.el_table_data = tableData;
                    return tableData;
                }, 
                
                
                //管理ip
                filterTable() {
                    let filtered = [...this.ipManageTableData];

                    if (this.ipSearchQuery.trim()) {
                        const ipQuery = this.ipSearchQuery.toLowerCase();
                        filtered = filtered.filter(item =>
                            item.server_addr?.toLowerCase().includes(ipQuery)
                        );
                    }

                    if (this.ruleSearchQuery.trim()) {
                        const ruleQuery = this.ruleSearchQuery.toLowerCase();
                        filtered = filtered.filter(item =>
                            item.rule_name?.toLowerCase().includes(ruleQuery)
                        );
                    }

                    if (this.mainIpFilter.trim()) {
                        filtered = filtered.filter(item =>
                            String(item.is_main_addr) === this.mainIpFilter
                        );
                    }

                    if (this.serverFilter.trim()) {
                        const serverQuery = this.serverFilter.toLowerCase();
                        filtered = filtered.filter(item =>
                            item.server_id?.toLowerCase().includes(serverQuery)
                        );
                    }

                    if (Array.isArray(this.dateRange) && this.dateRange.length === 2) {
                        const [start, end] = this.dateRange.map(date =>
                            new Date(date).setHours(0, 0, 0, 0) / 1000
                        );
                        const endOfDay = new Date(this.dateRange[1]).setHours(23, 59, 59, 999) / 1000;

                        filtered = filtered.filter(item => {
                            const itemTime = new Date(item.create_time * 1000).getTime() / 1000;
                            return itemTime >= start && itemTime <= endOfDay;
                        });
                    }

                    this.filteredData = filtered;
                    this.totalCount = this.filteredData.length;
                    this.showTotalCount = true;
                },
                
                searchIpDailog() {
                    this.showIpSearchDialog = true;  
                },
                resetManageForm() {
                    this.searchQuery = ''; 
                    this.ipManageTableData = [];
                    this.changeRuleId = null;
                    this.fetchIpData(); 
                }, 
                closeManageIp(){
                    this.showManageIp = false;
                    this.fetchIpData(); 
                   
                },
                
                 
                handleSearch() {
                    this.selectedIps = []; // 搜索时清空选中状态
                },  
                // 全选操作
                selectAll() {
                    this.$refs.ipDailogTable.clearSelection(); // 先清除所有选中状态
                    this.filteredData.forEach(row => {
                        this.$refs.ipDailogTable.toggleRowSelection(row, true); // 选择当前筛选后的每一行
                    });
                    this.selectedIps = this.filteredData.map(item => item.server_addr);
                },

                // 取消全选操作
                deselectAll() {
                    this.$refs.ipDailogTable.clearSelection(); // 清除所有选中状态
                    this.selectedIps = [];
                },

                // 反选操作
                invertSelection() {
                    const currentSelection = this.$refs.ipDailogTable.selection; // 获取当前选中的行
                    this.$refs.ipDailogTable.clearSelection(); // 清除所有选中状态

                    this.filteredData.forEach(row => {
                        const isSelected = currentSelection.some(selectedRow => selectedRow.server_addr === row.server_addr); // 检查当前行是否已选中
                        if (!isSelected) {
                            this.$refs.ipDailogTable.toggleRowSelection(row, true); // 未选中的行选中
                        }
                    });

                    this.handleSelectionChange(); // 更新选中的 IP 列表
                },

                handleSelectionChange(selection) {
                    this.selectedIps = this.$refs.ipDailogTable.selection.map(item => item.server_addr);
                }, 
               
                deleteSelectedIps() {
                    if (this.selectedIps.length === 0) {
                        //this.$message.warning('请选择要删除的 IP');
                        this.$message({
                            message: '请选择要删除的 IP',
                            type: 'danger',
                            customClass: 'custom-warning-message',
                        });
                        return;
                    }

                    // 弹出确认框，避免误操作
                    this.$confirm('确定要删除选中的 IP 吗？', '确认删除', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning',
                        })
                        .then(() => {
                            // 用户确认后发起删除请求
                            return axios.post('/index/deleteIps', {
                                ips: this.selectedIps,
                                rule_id: this.changeRuleId,
                            });
                        })
                        .then((response) => {
                            if (response.data.status === 'success') {
                                this.$message.success(response.data.message); 

                                 // 从 ipManageTableData 和 filteredData 中移除已删除的 IP
                                this.removeDeletedIpsFromData(); 

                                // 清空已选的 IP 列表
                                this.selectedIps = [];  
                                this.totalCount = this.filteredData.length; // 更新总条数 
                                 
                                
                                 
                            } else {
                                this.$message.error(response.data.message);
                            }
                        })
                        .catch((error) => {
                            if (error !== 'cancel') {
                                // 区分用户取消和请求错误
                                this.$message.error('删除选中的 IP 失败');
                            }
                        });
                }, 
                removeDeletedIpsFromData() {
                    // 移除 selectedIps 中的 IP 地址
                    this.ipManageTableData = this.ipManageTableData.filter(
                        item => !this.selectedIps.includes(item.server_addr)
                    );

                    // 重新计算并更新 filteredData
                    this.filterTable(); // 确保筛选后的数据也是最新的
                }, 

                //添加iP 
                handleScroll() {
                    const tableWrapper = this.$el.querySelector('.el-table__body-wrapper');
                    
                    if (!tableWrapper) return;
                    const scrollTop = tableWrapper.scrollTop;
                    const scrollHeight = tableWrapper.scrollHeight;
                    const clientHeight = tableWrapper.clientHeight;

                    // 如果滚动超过2/3高度时，显示按钮
                    this.showBackToTop = scrollTop > (scrollHeight - clientHeight) * 2 / 3; 
                   
                    //this.showBackToBottom = scrollTop == 0;
                },
                scrollToTop() {
                    const tableWrapper = this.$el.querySelector('.el-table__body-wrapper');
                    tableWrapper.scrollTo({ top: 0, behavior: 'smooth' });
                },
                scrollToBottom() {
                    const mainContainer = document.querySelector(".el-table__body-wrapper");
                    if (mainContainer) {
                        mainContainer.scrollTo({ top: mainContainer.scrollHeight, behavior: "smooth" });
                    }
                }, 
                handleTableScroll(event) {
                    const scrollContainer = event.target;
                    const scrollPosition = scrollContainer.scrollTop;
                    const containerHeight = scrollContainer.scrollHeight - scrollContainer.clientHeight;

                    // 显示“回到顶部”按钮逻辑
                    this.showManBackToTop = scrollPosition > (containerHeight) * 1 / 3;
                    
                },
                manScrollToTop() {
                    // Get the correct scrollable element within the el-table
                    const container = this.$refs.ipDailogTable?.$el.querySelector('.el-table__body-wrapper');
                    if (container) {
                        container.scrollTo({ top: 0, behavior: 'smooth' }); // Smooth scrolling to the top
                    } else {
                        console.warn('Scroll container not found for ipDailogTable');
                    }
                }, 
                handleDialogClose() {
                    this.showPopup = false;
                    this.resetForm(); // 重置表单
                    this.fetchIpData(); 
                },  
                resetForm() {
                    this.ipForm = { 
                        serverAddr: '',
                        serverAddrOne: '',
                    }; 
                },
                submitIpForm() {
                    axios.post('/index/ip_manage_add', this.ipForm, {
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    })
                    .then((response) => {
                        const { notIp = [], duplicateIp = [], status, message } = response.data; 
                         
                        let errorMessages = [];

                        if (duplicateIp.length > 0) {
                            errorMessages.push(`${duplicateIp.join('、')} IP 已存在，不能重复加入!<br>`);
                        }
                        if (notIp.length > 0) {
                            errorMessages.push(`${notIp.join('、')} IP 不符合规范，添加失败!<br>`);
                        }
                        // 如果有错误信息则展示，否则展示成功提示
                        if (errorMessages.length > 0) {
                            this.showMessage('error', errorMessages.join(''));
                        } else if (status === 'success') {
                            this.showMessage('success', 'IP 地址添加成功');
                            this.handleDialogClose();
                        } else {
                             
                            this.showMessage('error', message || '添加失败');
                        }
                    })
                    .catch(() => {
                        //this.showMessage('error', '添加 IP 地址失败');
                    });
                }, 
                showMessage(type, msg) {
                    this.$message({
                        type: type,
                        message: msg,
                        duration: 5000,
                        showClose: true,
                        dangerouslyUseHTMLString: true // 允许 HTML 渲染
                    });
                }, 
                //添加iP  
                openAddDialog(rule, group) { 
                    this.newIpDetails.rule_name = rule;
                    this.newIpDetails.group_id = group.replace("服务器", "").trim();
                    this.newIpDetails.server_addr = '';
                    this.newIpDetails.is_main_addr = false;
                    this.addDialogVisible = true;
                },
                saveNewIp() {
                    axios.post('/index/addIp', this.newIpDetails)
                        .then(response => {
                            if (response.data.status === 'success') {
                                this.$message.success('IP 添加成功');
                                this.addDialogVisible = false;  
                                
                                let groupId = this.newIpDetails.group_id; 
                                this.setAddCount(groupId); 
                                this.fetchIpData();
                            } else {
                                this.$message.error(response.data.message);
                            }
                        })
                        .catch(error => {
                            console.error('IP 添加失败:', error);
                            this.$message.error('IP 添加失败，请稍后重试');
                        });
                },
                setDeleteCount(groupId){
                    this.groups.some(group => {  
                        return group.subGroups.some(subGroup => { 
                            let nameId = subGroup.name.replace("服务器", "").trim(); 
                            let count = subGroup.count - 1;
                            if (nameId === groupId) {
                                this.$set(subGroup, 'count', count);
                                return true;  
                            }
                            return false;
                        }); 
                        return false;
                    });  
                },
                setAddCount(groupId){
                    this.groups.some(group => {  
                            return group.subGroups.some(subGroup => { 
                                let nameId = subGroup.name.replace("服务器", "").trim(); 
                                let count = subGroup.count + 1;
                                if (nameId === groupId) {
                                    this.$set(subGroup, 'count', count);
                                    return true;  
                                }
                                return false;
                            }); 
                        return false;
                    }); 
                },
               
                
                transformData(data) {
                    return Object.entries(data).map(([room, groups]) => ({
                        room,
                        groups: Object.entries(groups).map(([key, value]) => ({
                            groupId: key,
                            time: this.formatTimestamp(value.time),
                            ips: value.ips,
                            count:value.count,
                        }))
                    }));
                },
                processIpDetails(allData) {
                    this.ipDetails = {}; // Clear old data
                    allData.forEach(ipInfo => {
                        console.log(ipInfo);
                        const createDate = this.formatTimestamp(ipInfo.create_time);  
                        const updateDate = this.formatTimestamp(ipInfo.update_time); 
                        const rentTime = this.formatTimestamp(ipInfo.rent_time);  
                        // let status = ipInfo.status;
                        // let showStatus = '';
                        // if(status > 0){
                        //     showStatus = '<span style="color:red">禁用</span>';
                        // }else{
                        //     showStatus = '<span style="color:green">启用</span>';
                        // }
                        this.ipDetails[ipInfo.server_addr] = `<strong>(点击,查看详情,鼠标+ctrl键同时操作复制IP)</strong> 
                        <br>
                        租用时间: ${rentTime}<br>创建时间: ${createDate}<br>更新时间: ${updateDate}<br>`;
                        this.currentIpDetails[ipInfo.server_addr] = ipInfo;
                    });
                },  
                handleServerClick(event, ip) {
                    if (event.ctrlKey) {
                        // 按下 Shift 键时，进行复制操作
                        this.copyOneIp(ip); 
                    } else {
                        // 未按下 Shift 键时，执行添加操作
                        this.showIpDetails(ip);
                    }
                }, 
                searchIpDetail(){
                    let ip = this.inputIpVal;
                    this.showIpDetails(ip); 
                }, 
                closeIpSearch() {
                    this.showIpSearchDialog = false;
                    this.inputIpVal = '';
                }, 
                deleteIpByGroup(rule_name, server_id){ 
                    server_id = server_id.replace("服务器", "").trim();
                    this.$confirm(`确定要删除该组 IP 数据吗?`, "提示", {
                        confirmButtonText: "确定",
                        cancelButtonText: "取消",
                        type: "warning"
                    })
                    .then(() => { 
                            axios.post('/index/deleteIpByGroup', { 
                                server_id
                            })
                            .then(response => {
                                if (response.data.status === 'success') {
                                    this.$message.success(response.data.message); 
                                    this.ipDetailsVisible = false;
                                    this.fetchIpData();
                                } else {
                                    this.$message.error(response.data.message); 
                                }
                            })
                            .catch(() => {
                                this.$message.error('请求失败');
                            });
                        
                    })
                    .catch(() => {
                        this.$message.info("取消删除");
                    }); 
                },

                rentIpTime(rule_name, server_id) {
                    // Open a custom dialog for selecting the date-time
                    this.selectedRuleName = rule_name;
                    this.selectedServerId = server_id.replace("服务器", "").trim();
                    this.selectedRentTime = null;
                    this.showDateTimeDialog = true; // This controls the visibility of a custom dialog
                },
                submitRentTime() {
                    if (!this.selectedRentTime) {
                        this.$message.warning('请选择租用时间');
                        return;
                    }
                    
                    axios.post('/index/rentIpTime', {
                        rule_name: this.selectedRuleName,
                        server_id: this.selectedServerId,
                        rent_time: this.selectedRentTime // Pass selected time to backend
                    })
                    .then(response => {
                        if (response.data.status === 'success') {
                            const newTimeValue = response.data.time || '';
                            this.groups.some(group => { 
                                return group.subGroups.some(subGroup => { 
                                    let name = subGroup.name.replace("服务器", "").trim(); 
                                    if (name == this.selectedServerId) {
                                        this.$set(subGroup, 'time', newTimeValue);
                                        return true; // Terminate the loop once found
                                    }
                                    return false;
                                }); 
                                return false;
                            });
                            this.fetchIpData();
                            this.$message.success(response.data.message);
                        } else {
                            this.$message.error(response.data.message);
                        }
                    })
                    .catch(() => {
                        this.$message.error('请求失败');
                    })
                    .finally(() => {
                        this.showDateTimeDialog = false; // Close the dialog
                    });
                },
                
                copyOneIp(ips) {  
                    let ipList = ips.replace(/主|落地页/g, "").trim(); 
                    if (navigator.clipboard && navigator.clipboard.writeText) {
                    
                        navigator.clipboard.writeText(ipList)
                        .then(() => {
                            alert('IP 已复制');
                        })
                        .catch(err => {
                            console.error('复制失败:', err);
                            alert('复制失败，请手动复制');
                        });
                    } else { 
                        this.fallbackCopyText(ipList);
                    }
                },

                copyIps(ruleName, groupName) { 
                    const ips = (this.rawData[ruleName] && this.rawData[ruleName][groupName.replace("服务器", "").trim()]) || [];
                    
                     
                    const ipList = ips.map(ipInfo => ipInfo.ip.replace("主", "").trim()).join('\n');
                    
                    if (!ipList) {
                        this.$message.warning("该组没有 IP 地址可以复制");
                        return;
                    }

                    // 使用 Clipboard API 复制 IP 地址
                    if (navigator.clipboard && navigator.clipboard.writeText) {
                        navigator.clipboard.writeText(ipList)
                            .then(() => {
                                this.$message.success("IP 地址已复制到剪贴板");
                            })
                            .catch(err => {
                                console.error("复制失败:", err);
                                this.$message.error("复制失败，请手动复制");
                            });
                    } else {
                        // 如果 Clipboard API 不可用，使用备用方案
                        this.fallbackCopyText(ipList);
                    }
                },

                fallbackCopyText(text) {
                    const textArea = document.createElement("textarea");
                    textArea.value = text;
                    document.body.appendChild(textArea);
                    textArea.style.position = "fixed";  // 避免影响布局
                    textArea.style.left = "-9999px";
                    textArea.select();

                    try {
                        const successful = document.execCommand("copy");
                        const msg = successful ? "IP 地址已复制到剪贴板" : "复制失败";
                        this.$message.success(msg);
                    } catch (err) {
                        console.error("无法复制:", err);
                        this.$message.error("无法复制");
                    }

                    document.body.removeChild(textArea);
                },
                getIpDetail(ip) {
                    let realIp = ip.replace(/主|落地页/g, "").trim(); 
                    return this.ipDetails[realIp] || 'No details available';
                },
                getContent(group){  
                    return `<strong>(点击,添加IP)</strong><br> 创建时间: ${group.time}<br> 
                    数量：${group.count}<br>`; 
                }, 
                getRuleCount(room){   
                    const total = this.ruleIpCount[room];
                    return `总量：${total}<br>`; 
                },
                updateRuleId(selectedRuleId) {
                    // 更新 rule_id 为当前选中的规则 ID
                    this.showCurrentIpDetails.rule_id = selectedRuleId;
                },
                showIpDetails(ip) { 
                    let realIp = ip.replace(/主|落地页/g, "").trim(); 
                    this.originalIp = realIp;

                    // 检查该 IP 的详细信息是否存在
                    if (!this.currentIpDetails[realIp]) {
                        this.$message.error("该IP不存在!");
                        return;
                    }

                    // 复制详细信息到 showCurrentIpDetails
                    this.showCurrentIpDetails = { ...this.currentIpDetails[realIp] };
                    
                    this.originalIpDetails = JSON.parse(JSON.stringify(this.showCurrentIpDetails));
                    this.ipDetailsVisible = true;
                },
                hasChanges() {
                    return JSON.stringify(this.showCurrentIpDetails) !== JSON.stringify(this.originalIpDetails);
                },
                saveIpDetails() { 
                    axios.post('/index/updateIpDetails', {
                        server_addr: this.originalIp,  
                        updated_details: this.showCurrentIpDetails  
                    })
                    .then(response => {
                        if (response.data.status == 'success') {
                            this.$message.success("IP 已成功更新");
                            this.ipDetailsVisible = false;
                            this.fetchIpData();  
                        } else {
                            this.$message.error(response.data.message);
                        }
                    })
                    .catch(error => {
                        console.error("更新失败:", error);
                        this.$message.error("更新失败，请重试");
                    });
                },
                deleteDialogIp(type){ 
                    this.$confirm(`确定要执行删除操作吗？`, "提示", {
                        confirmButtonText: "确定",
                        cancelButtonText: "取消",
                        type: "warning"
                    })
                    .then(() => {
                            axios.post('/index/deleteDialogIp', { 
                                deleteInfo: this.showCurrentIpDetails, 
                                type 
                            })
                            .then(response => {
                                if (response.data.status === 'success') {
                                    this.$message.success(response.data.message); 
                                    this.ipDetailsVisible = false; 
                                     
                                    let groupId = this.showCurrentIpDetails.server_id;
                                    this.setDeleteCount(groupId); 
                                    this.fetchIpData(); 
                                    this.inputIpVal = '';
                                     
                                } else {
                                    this.$message.error(response.data.message); 
                                }
                            })
                            .catch(() => {
                                this.$message.error('请求失败');
                            });
                        
                    })
                    .catch(() => {
                        this.$message.info("取消删除");
                    }); 
                },
                formatTimestamp(timestamp) {
                    // 检查timestamp是否为有效的日期字符串
                    if (typeof timestamp === 'string' && !isNaN(Date.parse(timestamp))) {
                        // 如果是有效的日期字符串，直接返回
                        return timestamp;
                    }
                    // 检查timestamp是否为有效的整数类型的时间戳
                    else if (typeof timestamp === 'number' && isFinite(timestamp)) {
                        // 如果是有效的整数类型的时间戳，转换为日期
                        const date = new Date(timestamp * 1000); // 转换为毫秒

                        const year = date.getFullYear();
                        const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始，需要+1
                        const day = String(date.getDate()).padStart(2, '0');
                        const hours = String(date.getHours()).padStart(2, '0');
                        const minutes = String(date.getMinutes()).padStart(2, '0');
                        const seconds = String(date.getSeconds()).padStart(2, '0');

                        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                    }
                    // 如果timestamp无效或为'无'，返回'无'
                    else {
                        return '无';
                    }
                },
                
                deleteSingleIpByIp(ip) {
                    this.$confirm(`确定要删除 IP: ${ip} 吗？`, "提示", {
                        confirmButtonText: "确定",
                        cancelButtonText: "取消",
                        type: "warning"
                    })
                    .then(() => {
                        axios.post('/index/deleteSingleIpByIp', { ip })
                            .then(response => {
                                if (response.data.status === 'success') {
                                    this.removeDeletTransformedData(ip);
                                    this.fetchIpData();
                                    this.$message.success(`IP ${ip} 已删除`);  
                                } else {
                                    this.$message.error(response.data.message);
                                }
                            })
                            .catch(() => {
                                this.$message.error('请求失败');
                            });
                        
                    })
                    .catch(() => {
                        this.$message.info("取消删除");
                    });
                },
                removeDeletTransformedData(ip) {
                    this.transformedData.forEach(room => {
                        room.groups.forEach(group => {
                            group.ips = group.ips.filter(ipItem => ipItem.ip !== ip);
                        });
                    });
                    this.ipManageTableData = this.ipManageTableData.filter(
                        item => item.server_addr !== ip
                    );
                    this.filterTable(); 
                    // 强制更新视图
                    this.$forceUpdate();
                } 
        
      }
    });
  </script>

<style scoped>
    .table-container-wrapper {
      position: relative;  
    }

    .table-container {  
      overflow-y: auto;
      overflow-x: auto;
      margin-top:  60px;
    }  
    .back-to-top, .scroll-to-bottom {
      position: fixed;
      right: 30px;
      background-color: #409EFF;
      color: white;
      border: none;
      padding: 10px;
      border-radius: 5px;
      cursor: pointer;
      z-index: 1000;
    }

    .back-to-top {
      bottom: 30px;
    }

    .scroll-to-bottom {
      top: 30px;
    }
     
    .el-table th {
      background-color: #f5f7fa;
      font-weight: bold;
      text-align: center;
      z-index: 0; /* 降低z-index，防止覆盖fixed-header */
    }
    .el-table td {
      text-align: center;
    }
    .dialog-buttons {
      display: flex;
      justify-content: space-around;
      margin-top: 20px;
    }
    .ip-details {
      cursor: pointer;
      color: #409EFF;
    } 
   
    .scroll-to-bottom.show {
      display: block;
    }  

    .inputWidth{
        width: 200px;
    }
  
    .fixed-header {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      background-color: white;
      z-index: 10; /* 提高z-index，使其位于el-table之上 */
      padding: 10px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
  
    .el-dialog__wrapper {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      overflow: hidden;
      margin: 0;
    }
  
    .el-dialog__body {
      padding: 10px 10px;
      color: #606266;
      font-size: 14px;
      word-break: break-all;
    }

    .el-dialog {
        margin-top: 10vh !important; 
    }

    .man_scroll_to_top{
        position: absolute; 
        bottom: 10px; 
        right: 5px; 
        z-index: 20; 
        /* background: rgb(64, 203, 64);  */
        color: white; 
    } 

    /* .el-table--border th.el-table__cell, .el-table__fixed-right-patch {
        border-bottom: 1px solid rgb(137, 170, 167);
    } 
     
    .el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf {
        border-bottom: 1px solid rgb(137, 170, 167);
    }
    
    .el-table--border .el-table__cell, .el-table__body-wrapper .el-table--border.is-scrolling-left ~ .el-table__fixed {
        border-right: 1px solid rgb(137, 170, 167);
    } 
    .el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
        background-color: rgb(137, 170, 167);
    }
    .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
        background-color: #c7bdc1;
    }
    .el-table--border, .el-table--group {
        border: 1px solid rgb(137, 170, 167);
    } */

    
  </style>
  
</body>
</html>
